home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
051-075
/
disk_058
/
newzap
/
sources
/
readilbm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
7KB
|
255 lines
#include "iff.h"
extern void *IntuitionBase,*GfxBase,*DiskfontBase;
/* READILBM.C : NewZAP support routines - (c) 1986 John Hodgson */
#define DISK_ERR 1 /* error processing */
#define IFF_ERR 2
#define OUT_OF_MEM 3
#define EXPAND_ERR 4
#define BAD_MODE 5
#define MakeID(a,b,c,d) ((a)<<24L | (b)<<16L | (c)<<8 | (d))
#define ID_FORM MakeID('F','O','R','M')
#define ID_ILBM MakeID('I','L','B','M')
#define ID_BMHD MakeID('B','M','H','D')
#define ID_CAMG MakeID('C','A','M','G')
#define ID_CMAP MakeID('C','M','A','P')
#define ID_BODY MakeID('B','O','D','Y')
#define cmpByteRun1 1
#define ROUNDODDUP(a) (((a)+1)&(~1L))
typedef struct {
long ckID,ckSize;
} Chunk;
typedef struct {
short w,h,x,y;
char nPlanes,masking,compression,pad1;
short transparentColor;
char xAspect, yAspect;
short pageWidth,pageHeight;
} BitMapHeader;
short Mode;
unsigned char *pdiskptr;
#define SafeRead(a,b,c) if (ReadNEW(a,b,c)==-1L) \
{ CloseNEW(a); return(DISK_ERR); }
void *AllocMem(),*AllocRaster();
/************************************************************************
* *
* Routine name(s) : ReadILBM() *
* Author : D. John Hodgson *
* Environment : Aztec "C", default *
* *
* ReadILBM attempts to read an IFF file into an user-supplied *
* bitmap. Returns TRUE if successful. Brushes supported. *
* *
* OPTIONS : Filespec reflects user-supplied pointer to IFF file in *
* RAM if mode argument is non-zero. Otherwise, disk. *
* *
* LIMITATIONS : Bare-bones ILBM; no masking, CATS/LISTS/PROPS. *
* All other graphics (compressed or not) supported. *
************************************************************************/
void *OpenNEW(name,accessMode)
unsigned char *name;
long accessMode;
{
struct FileHandle *Open();
if (!Mode) return(Open(name,accessMode));
pdiskptr=name; /* initialize pseudo-disk RAM ptr */
return(pdiskptr);
}
long ReadNEW(file,buffer,length)
struct FileHandle *file;
char *buffer;
long length;
{
long Read();
if (!Mode) return(Read(file,buffer,length));
movmem(pdiskptr,buffer,(unsigned int)length);
pdiskptr+=length;
return(length);
}
long SeekNEW(file,position,tmode)
struct FileHandle *file;
long position,tmode;
{
long Seek();
if (!Mode) return(Seek(file,position,tmode));
/* Note : RAM seek only supports one mode : OFFSET_CURRENT! */
if (tmode!=OFFSET_CURRENT) return(BAD_MODE);
pdiskptr+=position;
return((long)pdiskptr-position); /* Seek() returns previous position! */
}
void CloseNEW(file)
struct FileHandle *file;
{
if (!Mode) Close(file);
}
/* tag : core routines live here! */
ReadILBM(fspec,mode,picmap)
char *fspec; /* AmigaDOS filename */
short mode;
struct PicMap *picmap;
{
struct FileHandle *fp;
Chunk header;
BitMapHeader bmhd;
unsigned char colormap[MAXCOLORS][3],*bufstart,*sourcebuf;
short i;
long id;
Mode=mode;
setmem(picmap,sizeof(*picmap),0L);
if (!(fp=OpenNEW(fspec,MODE_OLDFILE))) return(DISK_ERR);
SafeRead(fp,&header,(long)sizeof(header));
if (header.ckID!=ID_FORM) { CloseNEW(fp); return(IFF_ERR); }
SafeRead(fp,&id,(long)sizeof(id));
if (id!=ID_ILBM) { CloseNEW(fp); return(IFF_ERR); }
for (;;) {
SafeRead(fp,&header,(long)sizeof(header));
if (header.ckID==ID_BODY) break;
switch(header.ckID) {
case ID_BMHD: SafeRead(fp,&bmhd,(long)sizeof(bmhd));
/* force WORD boundary for all pics */
bmhd.w=(bmhd.w + 0xf) & 0xfff0;
break;
case ID_CMAP: SafeRead(fp,&colormap[0][0],(long)header.ckSize);
for (i=0;i<header.ckSize/3;i++)
picmap->colormap[i]=colormap[i][2]>>4 |
colormap[i][1] & 0xf0 |
(colormap[i][0] & 0xf0)<<4;
break;
case ID_CAMG: SafeRead(fp,&picmap->ViewModes,(long)header.ckSize);
break;
default: SeekNEW(fp,ROUNDODDUP(header.ckSize),OFFSET_CURRENT);
}
}
/* make some forced assumptions if CAMG chunk unavailable */
if (!picmap->ViewModes) {
if (bmhd.w>LOWIDTH) picmap->ViewModes=HIRES;
if (bmhd.h>LOHEIGHT) picmap->ViewModes|=LACE;
}
/* Read planes into RAM for ease if decompression */
if (Mode) sourcebuf=bufstart=pdiskptr; /* memory-resident IFF? */
else { /* disk-resident IFF? */
if (!(sourcebuf=bufstart=AllocMem((long)header.ckSize,MEMF_PUBLIC)))
return(OUT_OF_MEM);
SafeRead(fp,sourcebuf,(long)header.ckSize); CloseNEW(fp);
}
InitBitMap(&picmap->BitMap,(long)bmhd.nPlanes,(long)bmhd.w,(long)bmhd.h);
/* if we -REALLY- need a blank page, zero after allocating! */
for (i=0;i<bmhd.nPlanes;i++)
if (!(picmap->BitMap.Planes[i]=AllocRaster((long)bmhd.w,(long)bmhd.h))) {
FreeBitMap(&picmap->BitMap);
return(OUT_OF_MEM);
}
i=Expand(&bmhd,bufstart,&picmap->BitMap);
if (!Mode) FreeMem(bufstart,(long)header.ckSize);
return(i); /* error if unpacking prob */
}
FreeBitMap(bitmap)
struct BitMap *bitmap;
{
short i;
/* take into acct partially allocated maps (due to error) */
for (i=0;i<bitmap->Depth;i++) {
if (bitmap->Planes[i]) FreeRaster(
bitmap->Planes[i],(long)bitmap->BytesPerRow*8,(long)bitmap->Rows);
}
setmem(bitmap,sizeof(bitmap),0L); /* prevent dbl-dealloc errs */
}
Expand(bmhd,sourcebuf,bitmap) /* Fast line decompress/deinterleave */
BitMapHeader *bmhd;
register char *sourcebuf;
struct BitMap *bitmap;
{
register char n,*destbuf; /* in order of preferred allocation */
register short plane,rowlen,rowbytes,i;
rowlen=(bmhd->w)>>3;
for (i=0;i<bmhd->h;i++) /* process n lines/screen */
for (plane=0;plane<bmhd->nPlanes;plane++) { /* process n planes/line */
destbuf=(char *)(bitmap->Planes[plane])+rowlen*i;
if (bmhd->compression==cmpByteRun1) { /* compressed screen? */
rowbytes=rowlen;
while (rowbytes>0) { /* unpack until 1 scan-line complete */
n=*sourcebuf++; /* fetch block run marker */
/* uncompressed block? copy n bytes verbatim */
if (n>=0) {
++n;
movmem(sourcebuf,destbuf,(unsigned int)n);
rowbytes-=n; destbuf+=n; sourcebuf+=n;
}
else { /* compressed block? expand n duplicate bytes */
n=-n+1;
setmem(destbuf,(unsigned int)n,(unsigned int)*sourcebuf);
rowbytes -=n; sourcebuf++; destbuf+=n;
}
} /* finish unpacking line */
if (rowbytes) return(EXPAND_ERR); /* shouldn't be any left over! */
}
else { /* uncompressed? just copy */
movmem(sourcebuf,destbuf,(unsigned int)rowlen);
sourcebuf+=rowlen; destbuf+=rowlen;
}
} /* finish interleaved planes, lines */
return(0); /* good result! */
}